package me.project.android_service.controller;

import cn.hutool.core.lang.UUID;
import cn.soboys.restapispringbootstarter.Result;
import cn.soboys.restapispringbootstarter.annotation.Limit;
import cn.soboys.restapispringbootstarter.authorization.UserJwtToken;
import cn.soboys.restapispringbootstarter.enums.LogApiTypeEnum;
import cn.soboys.restapispringbootstarter.enums.LogCURDTypeEnum;
import cn.soboys.restapispringbootstarter.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.lettuce.core.pubsub.PubSubOutput;
import io.swagger.v3.oas.annotations.tags.Tag;
import me.project.android_common.domain.SendData;
import me.project.android_service.service.IAndroidInfoService;
import me.project.android_service.service.IDataPointService;
import me.project.common.exception.HttpStatus;
import me.project.android_common.domain.AndroidInfo;
import me.project.android_common.domain.DataPoint;
import org.springframework.integration.mapping.support.JsonHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.messaging.Message;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static io.lettuce.core.pubsub.PubSubOutput.Type.message;

@RestController
@Tag(name = "AndroidInfoController")
public class AndroidInfoController {

    @Resource
    private IAndroidInfoService androidInfoService;

    @Resource
    private IDataPointService dataPointService;

    @Resource
    KafkaTemplate<Object, Object> kafkaTemplate;

    @Resource
    private UserJwtToken userJwtToken;

    @PostMapping("/Upload_A_info")
    @Transactional(rollbackFor = RuntimeException.class)
    @Limit(key = "chat", name = "接口限流", period = 10, count = 3)
    @Log(value = "上传安卓Info", apiType = LogApiTypeEnum.USER, CURDType = LogCURDTypeEnum.RETRIEVE)
    public Result uploadAndroidInfo(@Validated @RequestBody AndroidInfo androidInfo) {
        AndroidInfo existingAndroidInfo = androidInfoService.getOne(new QueryWrapper<AndroidInfo>().eq("code", androidInfo.getCode()));

        // 如果找到现有的AndroidInfo，并检查字段是否有变化
        if (existingAndroidInfo != null && fieldsChanged(existingAndroidInfo, androidInfo)) {
            return handleAndroidInfoUpdate(existingAndroidInfo, androidInfo);
        } else if (existingAndroidInfo == null) {
            // 如果没有找到现有AndroidInfo，尝试根据其他条件创建新记录
            return handleNewAndroidInfo(androidInfo);
        }

        // 如果没有字段变化且不需要创建新记录，返回成功但无变化的信息
        return Result.buildSuccess("No changes detected; operation successful.");
    }

    private Result handleAndroidInfoUpdate(AndroidInfo existingAndroidInfo, AndroidInfo newAndroidInfo) {
        if (existingAndroidInfo.getIsPackage() == 0) {
            boolean exists = androidInfoService.existsWithAppNameOrPackageName(existingAndroidInfo.getAppName(), newAndroidInfo.getPackageName());
            if (exists) {
                return Result.buildFailure(HttpStatus.CONFLICT.getCode(), "AppName or PackageName already exists.");
            }
            kafkaTemplate.send("android_generate", new SendData(existingAndroidInfo.getUuid(), "http://localhost:10030/apis/android/"));
            return Result.buildSuccess("Repacking...");
        }
        return updateAndroidInfo(existingAndroidInfo, newAndroidInfo);
    }

    private Result handleNewAndroidInfo(AndroidInfo androidInfo) {
        boolean exists = androidInfoService.existsWithAppNameOrPackageName(androidInfo.getAppName(), androidInfo.getPackageName());
        if (exists) {
            return Result.buildFailure(HttpStatus.CONFLICT.getCode(), "AppName or PackageName already exists.");
        }
        // 这里处理创建新AndroidInfo的逻辑
        String uniqueId = UUID.randomUUID().toString().replace("-", "");
        androidInfo.setUuid(uniqueId);
        String packageName = androidInfo.getPackageName();
        String[] parts = packageName.split("\\.");
        String lastWord = parts[parts.length - 1];
        androidInfo.setIconName(lastWord.trim().toLowerCase(Locale.ROOT));
        System.out.println(androidInfo);
        boolean insert = androidInfoService.save(androidInfo);
        if (insert) {
            Set<DataPoint> dataPoints = androidInfo.getDataPoints();
            List<DataPoint> dataPointList = dataPoints.stream().peek(dataPoint -> {
                dataPoint.setAndroidId(androidInfo.getId());
            }).collect(Collectors.toList());
            boolean b = dataPointService.saveBatch(dataPointList);
            if (b){
                kafkaTemplate.send("android_generate",new SendData(uniqueId, "http://localhost:10030/apis/android/"));
            }
            return Result.buildSuccess("uuid-->" + uniqueId);
        }
        return Result.buildFailure(HttpStatus.REQUEST_TIMEOUT.getCode(), HttpStatus.REQUEST_TIMEOUT.getMessage());
    }

    private Result updateAndroidInfo(AndroidInfo existingAndroidInfo, AndroidInfo newAndroidInfo) {
        if ((!Objects.equals(existingAndroidInfo.getAppName(), newAndroidInfo.getAppName()) ||
                !Objects.equals(existingAndroidInfo.getPackageName(), newAndroidInfo.getPackageName())) &&
                androidInfoService.existsWithAppNameOrPackageName(newAndroidInfo.getAppName(), newAndroidInfo.getPackageName())) {
            return Result.buildFailure(HttpStatus.CONFLICT.getCode(), "AppName or PackageName already exists.");
        }
        // 更新字段
        updateFields(existingAndroidInfo, newAndroidInfo);
        // 这里处理更新现有AndroidInfo的逻辑
        boolean update = androidInfoService.updateById(existingAndroidInfo);
        if (update) {
            dataPointService.remove(new QueryWrapper<DataPoint>().eq("androidId", existingAndroidInfo.getId()));
            Set<DataPoint> dataPoints = newAndroidInfo.getDataPoints();
            List<DataPoint> dataPointList = dataPoints.stream().peek(dataPoint -> {
                dataPoint.setAndroidId(existingAndroidInfo.getId());
            }).collect(Collectors.toList());
            dataPointService.saveBatch(dataPointList);
            kafkaTemplate.send("android_generate", new SendData(existingAndroidInfo.getUuid(), "http://localhost:10030/apis/android/"));
            return Result.buildSuccess("AndroidInfo updated successfully.Repacking...");
        }
        return Result.buildFailure(HttpStatus.REQUEST_TIMEOUT.getCode(), HttpStatus.REQUEST_TIMEOUT.getMessage());
    }

    private void updateFields(AndroidInfo existingAndroidInfo, AndroidInfo newAndroidInfo) {
        // 对每个字段进行检查，如果需要更新，则进行赋值操作
        if (!Objects.equals(existingAndroidInfo.getAppName(), newAndroidInfo.getAppName())) {
            existingAndroidInfo.setAppName(newAndroidInfo.getAppName());
        }
        if (!Objects.equals(existingAndroidInfo.getPackageName(), newAndroidInfo.getPackageName())) {
            existingAndroidInfo.setPackageName(newAndroidInfo.getPackageName());
        }
        if (!Objects.equals(existingAndroidInfo.getUrl(), newAndroidInfo.getUrl())) {
            existingAndroidInfo.setUrl(newAndroidInfo.getUrl());
        }
        if (!Objects.equals(existingAndroidInfo.getAdjustToken(), newAndroidInfo.getAdjustToken())) {
            existingAndroidInfo.setAdjustToken(newAndroidInfo.getAdjustToken());
        }
        if (!Objects.equals(existingAndroidInfo.getAppsflyerToken(), newAndroidInfo.getAppsflyerToken())) {
            existingAndroidInfo.setAppsflyerToken(newAndroidInfo.getAppsflyerToken());
        }
        if (!Objects.equals(existingAndroidInfo.getChannel(), newAndroidInfo.getChannel())) {
            existingAndroidInfo.setChannel(newAndroidInfo.getChannel());
        }
        if (!Objects.equals(existingAndroidInfo.getIconUrl(), newAndroidInfo.getIconUrl())) {
            existingAndroidInfo.setIconUrl(newAndroidInfo.getIconUrl());
        }
        if (!Objects.equals(existingAndroidInfo.getCode(), newAndroidInfo.getCode())) {
            existingAndroidInfo.setCode(newAndroidInfo.getCode());
        }
        if (!Objects.equals(existingAndroidInfo.getDataPoints(), newAndroidInfo.getDataPoints())) {
            existingAndroidInfo.setDataPoints(newAndroidInfo.getDataPoints());
        }
        String packageName = newAndroidInfo.getPackageName();
        String[] parts = packageName.split("\\.");
        String lastWord = parts[parts.length - 1];
        existingAndroidInfo.setIconName(lastWord.trim().toLowerCase(Locale.ROOT));
    }


    private boolean fieldsChanged(AndroidInfo existing, AndroidInfo submitted) {
        return !Objects.equals(existing.getAppName(), submitted.getAppName()) ||
                !Objects.equals(existing.getPackageName(), submitted.getPackageName()) ||
                !Objects.equals(existing.getUrl(),submitted.getUrl()) ||
                !Objects.equals(existing.getAdjustToken(),submitted.getAdjustToken()) ||
                submitted.getIsPackage() == 0 ||
                !Objects.equals(existing.getAppsflyerToken(),submitted.getAppsflyerToken());
    }

    @GetMapping(value = {"/get_A_info"})
    @Transactional(rollbackFor = RuntimeException.class)
    public AndroidInfo getAndroidInfo(@RequestParam("uuid") @Validated String UUID) {
        AndroidInfo selectedInfo = androidInfoService.selectAndroidInfoWithPoints(UUID);
        System.out.println("打包时请求的数据：-->>" + selectedInfo);
        return selectedInfo;
    }

    @GetMapping("/generate")
    @Transactional(rollbackFor = RuntimeException.class)
    public Result generate(@RequestParam("userId") @Validated String userId) {
//        userJwtToken.rememberMe = true;
//        String token = userJwtToken.createdToken(userId,);
        return Result.buildSuccess("token");
    }


}
